package model;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.List;

import com.sun.xml.internal.bind.v2.runtime.unmarshaller.XsiNilLoader.Array;

import controller.Controller;

public class ConversionMethods {

	private Controller controller;

	public ConversionMethods(Controller controller) {
		this.controller = controller;
	}

	/**
	 * Berechnet den mittleren Aspirationscode aus einer Liste von
	 * Aspirationscodes.
	 * 
	 * @param values
	 *            Die Liste mit Aspirationscodes
	 * @return Einen String, der dem/den mittleren Aspirationscode/s entspricht.
	 */
	public static String calculateAverageAspirationCode(String[] values) {
		if (values.length == 0) {
			return "";
		}

		StringBuffer buffer = new StringBuffer();

		HashMap<Character, Integer> myMap = new HashMap<Character, Integer>();

		for (int i = 0; i < values.length; i++) {
			String currentCode = values[i];
			for (int j = 0; j < 3; j++) {
				char currentCharacter = currentCode.charAt(j);
				if (myMap.containsKey(currentCharacter)) {
					myMap.put(currentCharacter, myMap.get(currentCharacter)
							.intValue() + (3 - j));
				} else {
					myMap.put(currentCharacter, 3 - j);
				}
			}
		}

		ArrayList<Character> chars = getMaxChars(myMap);
		ArrayList<String> permutations = getAllPermutations(chars);
		ArrayList<String> filteredPermutations = new ArrayList<String>();
		int max = 0;
		for (String current : permutations) {
			if (!(current.charAt(0) == current.charAt(1)
					|| current.charAt(0) == current.charAt(2)
					|| current.charAt(1) == current.charAt(2)
					|| myMap.get(current.charAt(0)) < myMap.get(current
							.charAt(1))
					|| myMap.get(current.charAt(0)) < myMap.get(current
							.charAt(2)) || myMap.get(current.charAt(1)) < myMap
					.get(current.charAt(2)))) {
				if (myMap.get(current.charAt(0)) + myMap.get(current.charAt(1))
						+ myMap.get(current.charAt(2)) > max) {
					max = myMap.get(current.charAt(0))
							+ myMap.get(current.charAt(1))
							+ myMap.get(current.charAt(2));
				}
				filteredPermutations.add(current);
			}
		}
		for (String current : filteredPermutations) {
			if(myMap.get(current.charAt(0)) + myMap.get(current.charAt(1))
						+ myMap.get(current.charAt(2)) == max){
				buffer.append(current).append(" | ");
			}
		}
		
		

		return buffer.substring(0, buffer.length() - 3);
	}

	private static ArrayList<Character> getMaxChars(
			HashMap<Character, Integer> myMap) {
		ArrayList<Character> maxima = new ArrayList<Character>();
		int[] maxNumbers = { 0, 0, 0 };
		for (Character c : myMap.keySet()) {
			if (myMap.get(c) > maxNumbers[0]) {
				maxNumbers[2] = maxNumbers[1];
				maxNumbers[1] = maxNumbers[0];
				maxNumbers[0] = myMap.get(c);
			}
			if (myMap.get(c) > maxNumbers[1] && myMap.get(c) != maxNumbers[0]) {
				maxNumbers[2] = maxNumbers[1];
				maxNumbers[1] = myMap.get(c);
			}
			if (myMap.get(c) > maxNumbers[2] && myMap.get(c) != maxNumbers[1]
					&& myMap.get(c) != maxNumbers[0]) {
				maxNumbers[2] = myMap.get(c);
			}
		}

		for (Character c : myMap.keySet()) {
			if (myMap.get(c) == maxNumbers[0] || myMap.get(c) == maxNumbers[1]
					|| myMap.get(c) == maxNumbers[2]) {
				maxima.add(c);
			}
		}

		return maxima;
	}

	private static ArrayList<String> getAllPermutations(
			ArrayList<Character> chars) {
		ArrayList<String> result = new ArrayList<String>();

		for (int i = 0; i < chars.size(); i++) {
			for (int j = 0; j < chars.size(); j++) {
				for (int k = 0; k < chars.size(); k++) {
					result.add("" + chars.get(i) + chars.get(j) + chars.get(k));
				}
			}
		}
		return result;
	}

	public static String fieldToString(Job[][] jobArray) {
		StringBuffer sb = new StringBuffer();
		for (int x = 0; x < jobArray.length; x++) {
			for (int y = 0; y < jobArray[x].length; y++) {
				if (jobArray[x][y] == null) {
					sb.append("null").append('$');
				} else {
					sb.append(jobArray[x][y].getJobName()).append('$');
				}
			}
		}
		return sb.toString();
	}

	public static int[] containsJob(Job job, Job[][] jobs) {
		int[] result = { -1, -1 };
		for (int i = 0; i < jobs.length; i++) {
			for (int j = 0; j < jobs[i].length; j++) {
				if (job.equals(jobs[i][j])) {
					result[0] = i;
					result[1] = j;
					return result;
				}
			}
		}

		return result;
	}

	public Job[][] stringToJobArray(String input) {
		if (input == null || countChar(input, '$') != 81) {
			return null;
		}
		JobList joblist = controller.getJobList();
		Job[][] jobField = new Job[9][9];

		for (int x = 0; x < jobField.length; x++) {
			for (int y = 0; y < jobField[x].length; y++) {
				int position = input.indexOf('$');
				String jobName = input.substring(0, position);
				if (!jobName.equals("null")) {
					for (int i = 0; i < joblist.size(); i++) {
						Job job = joblist.get(i);
						if (job.getJobName().equals(jobName)) {
							jobField[x][y] = job;
						}
					}
				} else {
					jobField[x][y] = null;
				}
				input = input.substring(position + 1);
			}
		}
		return jobField;

	}

	public static String intArrayToString(int[][] values) {
		StringBuffer sb = new StringBuffer();
		for (int x = 0; x < values.length; x++) {
			for (int y = 0; y < values[x].length; y++) {
				sb.append(values[x][y]);
			}

		}
		return sb.toString();
	}

	public int[][] stringToIntArray(String str) {

		int[][] result = new int[9][9];
		if (str == null) {
			for (int x = 0; x < result.length; x++) {
				for (int y = 0; y < result.length; y++) {
					result[x][y] = -1;
				}
			}
			return result;
		}
		if (str.length() - countChar(str, '-') != 81) {
			return null;
		}

		int counter = 0;
		for (int x = 0; x < result.length; x++) {
			for (int y = 0; y < result[x].length; y++) {
				if (str.charAt(counter) == '-') {
					result[x][y] = Integer.parseInt(str.substring(counter,
							counter + 2));
					counter++;
				} else {
					result[x][y] = Integer.parseInt(str.substring(counter,
							counter + 1));
				}
				counter++;
			}
		}
		return result;
	}

	public static String evaluationToString(int[] values, String riasec) {
		StringBuffer buffer = new StringBuffer();
		buffer.append(riasec).append('$');
		for (int i = 0; i < values.length; i++) {
			buffer.append(values[i]).append('$');
		}
		return buffer.toString();
	}

	public static Object[] stringToEvaluation(String input) {
		Object[] result = new Object[29];
		if (input == null || input.isEmpty() || input == " ") {
			result[0] = "";
			for (int x = 1; x < result.length; x++) {
				result[x] = -1;
			}
			return result;
		}

		result[0] = input.substring(0, input.indexOf('$'));
		int counter = input.indexOf('$') + 1;
		for (int i = 1; i < 29; i++) {
			int position = input.indexOf('$', counter);
			String current = input.substring(counter, position);
			result[i] = Integer.parseInt(current);
			counter = position + 1;
		}
		return result;
	}

	public static int[] getIntArrayFromEvaluation(Object[] input) {
		if (input.length != 29) {
			return null;
		}
		int[] result = new int[28];
		for (int i = 1; i < 29; i++) {
			result[i - 1] = Integer.valueOf("" + input[i]);
		}
		return result;
	}

	private static int countChar(String input, char c) {
		int counter = 0;
		char[] x = input.toCharArray();
		for (char z : x) {
			counter += c == z ? 1 : 0;
		}
		return counter;
	}
}
